import {
  app,
  BrowserWindow,
  ipcMain,
  Menu
} from 'electron'
import StreamDownload from "../util/StreamDownload";
import Ping from "../util/Ping";
/**
 * Set `__static` path to static files in production
 * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
 */
if (process.env.NODE_ENV !== 'development') {
  global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
}

let mainWindow
const winURL = process.env.NODE_ENV === 'development' ?
  `http://localhost:9080` :
  `file://${__dirname}/index.html`

function createWindow() {
  Menu.setApplicationMenu(null);
  /**
   * Initial window options
   */
  mainWindow = new BrowserWindow({
    height: 680,
    useContentSize: true,
    width: 1400,
    show: false
  })
  mainWindow.maximize();
  mainWindow.show();
  mainWindow.loadURL(winURL)

  mainWindow.on('closed', () => {
    mainWindow = null
  })
}

app.on('ready', createWindow)

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  if (mainWindow === null) {
    createWindow()
  }
})

ipcMain.on('downloadFileStart', (event, {
  nodeData,
  testConfig
}) => {
  let testIndex = 0;
  let testTimes = 0;
  const downloadFileStart = () => {
    const nodeInfo = nodeData[testIndex];
    let startTime = process.uptime();
    let secSpeed = {};
    let errorMsg = "";
    let req = null;
    let totalSize = -1;
    let lastProgress = 0;
    mainWindow.webContents.send('setProcess', {
      progress: 0,
      speed: '-'
    });
    mainWindow.webContents.send('setInitvalue', {
      name: nodeInfo.name,
      times: testTimes + 1,
      total: "正在连接资源...",
      url: nodeInfo.url,
      index: testIndex + 1
    });
    ipcMain.on("skipNow", () => {
      if (req) req.abort();
    });
    ipcMain.on("stopAll", () => {
      if (req) req.abort();
      testIndex = nodeData.length;
    });
    if (nodeInfo) {
      StreamDownload.downloadFile(nodeInfo.url, (arg, res) => {
        const timeOut = nodeInfo.overtime || testConfig.overtime || -1;
        switch (arg) {
          case "start":
            startTime = res.time;
            req = res.req;
            totalSize = res.totalBytes;
            mainWindow.webContents.send('setInitvalue', {
              name: nodeInfo.name,
              times: testTimes + 1,
              total: res.totalBytes ? res.totalBytes : "未知",
              url: nodeInfo.url,
              index: testIndex + 1
            });
            if (timeOut > 0) {
              setTimeout(() => {
                if (req) req.abort();
              }, timeOut * 1000);
            }
            break;
          case "progress":
            const nowTime = Math.floor(res.time - startTime);
            if (!secSpeed[nowTime]) secSpeed[nowTime] = 0;
            secSpeed[nowTime] += res.chunkLen;
            let progressInteger = Math.floor(res.progress);
            if (lastProgress !== progressInteger) {
              let factTotal = 0;
              for (let speedKey in secSpeed) {
                if (secSpeed.hasOwnProperty(speedKey)) {
                  if (secSpeed[speedKey]) factTotal += secSpeed[speedKey];
                }
              }
              let avg = factTotal / Math.floor(nowTime);
              avg = avg ? avg : 0;
              mainWindow.webContents.send('setProcess', {
                progress: progressInteger,
                speed: secSpeed[nowTime - 1] ? secSpeed[nowTime - 1] : '-',
                predict: totalSize > 0 && avg ? totalSize / avg : '-',
                countdown: timeOut && timeOut !== -1 && nowTime ? timeOut - nowTime : '-'
              });
              lastProgress = progressInteger;
            }
            break;
            // 出现异常
          case "error":
            errorMsg = res.err.message;
            break;
          case "finished":
            const endTime = process.uptime();
            let low = 9999999999;
            let high = 0;
            let factTotal = 0;
            for (let speedKey in secSpeed) {
              if (secSpeed.hasOwnProperty(speedKey)) {
                if (secSpeed[speedKey] && secSpeed[speedKey] > high) high = secSpeed[speedKey];
                if (secSpeed[speedKey] && secSpeed[speedKey] < low) low = secSpeed[speedKey];
                if (secSpeed[speedKey]) factTotal += secSpeed[speedKey];
              }
            }
            if (!low || low === 9999999999) low = '-';
            if (!high) high = '-';
            let avg = factTotal / Math.floor(endTime - startTime);
            avg = avg ? avg : '-';
            // 将当前结果添加到结果集
            let completeProgress = (factTotal && totalSize) ? Math.floor((factTotal / totalSize).toFixed(2) * 100) + "%" : "-";
            if (!res.ok) {
              let factTotal = 0;
              if (secSpeed) {
                for (let speedKey in secSpeed) {
                  if (secSpeed.hasOwnProperty(speedKey)) {
                    if (secSpeed[speedKey]) factTotal += secSpeed[speedKey];
                  }
                }
              }
              let avg = factTotal / Math.floor(endTime - startTime);
              avg = avg ? avg : '-';
              // 不成功
              mainWindow.webContents.send('pushResult', {
                name: nodeInfo.name,
                times: testTimes + 1,
                time: endTime - startTime,
                msg: errorMsg ? errorMsg : '跳过',
                complete: completeProgress,
                predict: totalSize > 0 && avg ? totalSize / avg : '-',
                low,
                high,
                avg,
              });
            } else {
              mainWindow.webContents.send('pushResult', {
                name: nodeInfo.name,
                low,
                high,
                avg,
                complete: completeProgress,
                predict: totalSize > 0 && avg ? totalSize / avg : '-',
                times: testTimes + 1,
                time: process.uptime() - startTime,
                msg: "成功"
              });
            }
            // 当下载结束后，进入下一阶段
            testTimes++;
            if (nodeInfo.times) {
              if (testTimes >= nodeInfo.times) {
                testIndex++;
                testTimes = 0;
              }
            } else if (testConfig.totalTimes) {
              if (testTimes >= testConfig.totalTimes) {
                testIndex++;
                testTimes = 0;
              }
            }
            ipcMain.removeAllListeners('skipNow');
            ipcMain.removeAllListeners('stopAll');
            mainWindow.webContents.send('onSkipOrStop');
            if (testIndex >= nodeData.length)
              mainWindow.webContents.send('onTestOver');
            else downloadFileStart();
            break;
          default:
            break;
        }
      });
    }
  };
  if (testIndex >= nodeData.length) mainWindow.webContents.send('onTestOver', {});
  else downloadFileStart();
});

ipcMain.on('pingTestStart', (event, nodeData) => {
  let pingIndex = 0;
  const startPingTest = () => {
    const nodeInfo = nodeData[pingIndex];
    ipcMain.on("stopPingAll", () => {
      pingIndex = nodeData.length;
    });
    mainWindow.webContents.send('setInitvalue', {
      name: nodeInfo.name,
      ip: nodeInfo.ip,
      index: pingIndex + 1
    });
    Ping.start(nodeInfo.ip, res => {
      mainWindow.webContents.send('pushResult', {
        name: nodeInfo.name,
        ip: nodeInfo.ip,
        ...res
      });
      ipcMain.removeAllListeners('stopPingAll');
      mainWindow.webContents.send('onSkipOrStop');
      if (pingIndex < nodeData.length - 1) {
        pingIndex++;
        startPingTest();
      } else {
        mainWindow.webContents.send('onTestOver', {});
      }
    });
  }
  startPingTest();
});